home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 1 / LSD Compendium Deluxe 1.iso / a / text / manipulation / snap164.lha / snapgfx.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-30  |  11.5 KB  |  361 lines

  1. #if __SASC
  2. #include "snap.h"
  3. #endif
  4.  
  5. /* Auto: make
  6. */
  7.  
  8. IMPORT BOOL Kick36;
  9.  
  10. IMPORT struct GfxBase *GfxBase;
  11.  
  12. IMPORT struct SnapRsrc *SnapRsrc;
  13. IMPORT struct Image DiskImage;
  14. IMPORT struct Image ClipImage;
  15. IMPORT struct Gadget DiskGad;
  16. IMPORT struct Gadget ClipGad;
  17. IMPORT struct Gadget VProp, HProp;
  18. IMPORT struct PropInfo VInfo, HInfo;
  19. IMPORT struct Image VImage, HImage;
  20. IMPORT struct NewWindow Nw;
  21. IMPORT UBYTE *WindowTitle;
  22.  
  23. IMPORT LONG xl; /* leftmost x position */
  24. IMPORT LONG xr; /* rightmost x position */
  25. IMPORT LONG yt; /* topmost y position */
  26. IMPORT LONG yb; /* bottommost y position */
  27. IMPORT LONG mx, my; /* Mouse position in pixels */
  28.  
  29. #define GfxFrame 4L
  30. IMPORT Point OldFrame[];
  31. IMPORT Point NewFrame[];
  32. IMPORT LONG OFType;        /* Old frame type: ShortFrame/LongFrame */
  33. IMPORT UWORD Ptrn;
  34. IMPORT WORD Pattern[];
  35.  
  36. IMPORT struct RastPort MyRP;
  37. IMPORT struct BitMap MyBM;
  38. IMPORT struct Screen *theScreen;
  39. struct Layer_Info *LockedLayerInfo;
  40. IMPORT struct RastPort rp;
  41.  
  42. IMPORT struct timerequest MyTR;
  43.  
  44. IMPORT LONGBITS cancelsignal, donesignal, movesignal;
  45. IMPORT LONGBITS clicksignal, ticksignal, timersignal;
  46. IMPORT WORD action;
  47.  
  48. LONG TopBar;
  49. LONG LeftBar;
  50. LONG RightBar;
  51. LONG BottomBar;
  52. LONG ScreenFontHeight;
  53. struct TextFont *ScreenFont;
  54.  
  55. VOID FixHeights()
  56. {
  57.     struct Screen WBScreen;
  58.  
  59.     OpenWorkBench();
  60.     if (GetScreenData((char *)&WBScreen, (LONG)sizeof(struct Screen), WBENCHSCREEN, NULL)) {
  61.           /* Now this is a good practice */
  62.         TopBar = WBScreen.WBorTop + WBScreen.RastPort.TxHeight + 1;
  63.         LeftBar = WBScreen.WBorLeft;
  64.         RightBar = WBScreen.WBorRight;
  65.         BottomBar = WBScreen.WBorBottom;
  66.         ScreenFont = WBScreen.RastPort.Font;
  67.         if (!ScreenFont) {
  68.             Forbid();
  69.             ScreenFont = GfxBase->DefaultFont;
  70.             Permit();
  71.         }
  72.         ScreenFontHeight = ScreenFont->tf_YSize;
  73.     } else {
  74.           /* Sorry, but I don't realise how this could fail.
  75.              Well, if we're snapping on another screen and
  76.              WB is closed and it can't be opened by GetScreenData()...
  77.              Anyway, IF this should happen -- Use Topaz 8 */
  78.         TopBar = 10;
  79.         LeftBar = 2;
  80.         RightBar = 2;
  81.         BottomBar = 1;
  82.         ScreenFontHeight = 8;
  83.         Forbid();
  84.         ScreenFont = GfxBase->DefaultFont;
  85.         Permit();
  86.     }
  87. }
  88.  
  89. /* SnapGfx is the actual graphics snapper.
  90. ** It steals the bitmap data from the given rastport
  91. ** and puts it in a separate bitmap.
  92. ** It also prepares the NewWindow structure according
  93. ** to the snapped bitmap.
  94. ** The coordinates are assumed to be valid.
  95. */
  96.  
  97. struct GfxSnap *SnapGfx(rp)
  98. struct RastPort *rp;
  99. {
  100.     struct GfxSnap *GS;
  101.     LONG i;
  102.  
  103.     GS = Create(GfxSnap);
  104.     if (!GS) {
  105.         return NULL;
  106.     }
  107.  
  108.     GS->x = xl;
  109.     GS->y = yt;
  110.     GS->width = xr - xl + 1;
  111.     GS->height = yb - yt + 1;
  112.     if (xr < xl + MINWIDTH) {          /* Can't have too small windows */
  113.         xr = xl + MINWIDTH;
  114.     }
  115.     if (yb < yt + MINHEIGHT) {
  116.         yb = yt + MINHEIGHT;
  117.     }
  118.     GS->depth = rp->BitMap->Depth;
  119.     GS->viewmode = theScreen->ViewPort.Modes;
  120.     GS->pagew = theScreen->Width;
  121.     GS->pageh = theScreen->Height;
  122.     i = (GS->viewmode & HAM ? 16 : 1L << GS->depth);
  123.       /* Copy the color map in case we should need it later */
  124.     while (i--) {
  125.         ULONG col = GetRGB4(theScreen->ViewPort.ColorMap, i);
  126.         GS->rgb[i][0] = ((col >> 8) & 0x0f) << 4;
  127.         GS->rgb[i][1] = ((col >> 4) & 0x0f) << 4;
  128.         GS->rgb[i][2] = ((col >> 0) & 0x0f) << 4;
  129.     }
  130.       /* Set up a nice bitmap */
  131.     InitBitMap(&GS->BM, GS->depth, GS->width, GS->height);
  132.       /* Get a handle on the bitmap */
  133.     InitRastPort(&MyRP);
  134.     MyRP.BitMap = &GS->BM;
  135.     if (!AllocPlanes(&GS->BM, GS->width, GS->height)) {
  136.         FreePlanes(&GS->BM, GS->width, GS->height);
  137.         Kill(GS);
  138.         return NULL;
  139.     }
  140.       /* Copy the selected part of the screen */
  141.     ClipBlit(rp, xl, yt, &MyRP, 0L, 0L, GS->width, GS->height, 0xC0L);
  142.     if (!Kick36) {
  143.         VInfo.Flags |= PROPBORDERLESS;
  144.         HInfo.Flags |= PROPBORDERLESS;
  145.     }
  146.     CopyMem((char *)&DiskGad, (char *)&GS->DiskGad,
  147.       (LONG)sizeof(DiskGad) + sizeof(ClipGad) + sizeof(VProp) + sizeof(HProp) +
  148.       sizeof(VInfo) + sizeof(HInfo) + sizeof(VImage) + sizeof(HImage));
  149.     GS->topbar = TopBar;
  150.     GS->leftbar = LeftBar;
  151.     GS->rightbar = 18; /* (Kick36 ? RightBar : 18); */
  152.     GS->bottombar = 10;
  153.  
  154.     Nw.LeftEdge = xl;
  155.     Nw.TopEdge = yt;
  156.     Nw.Width = xr - xl + 1 + GS->leftbar + GS->rightbar;
  157.     Nw.Height = yb - yt + 1 + GS->topbar + GS->bottombar;
  158.     Nw.Flags &= ~(SIMPLE_REFRESH | SMART_REFRESH | NOCAREREFRESH);
  159.     Nw.Flags |= (SnapRsrc->flags & SIMPLEREFRESH ?
  160.       SIMPLE_REFRESH : SMART_REFRESH | NOCAREREFRESH);
  161.  
  162.     Nw.Title = WindowTitle;
  163.     Nw.MinWidth = MINWIDTH + 1 + GS->leftbar + GS->rightbar;
  164.     Nw.MinHeight = MINHEIGHT + 1 + GS->topbar + GS->bottombar;
  165.     Nw.MaxWidth = Nw.Width;
  166.     Nw.MaxHeight = Nw.Height;
  167.  
  168.     if (Kick36) Nw.Flags |= SIZEBBOTTOM|SIZEBRIGHT;
  169.  
  170.     return GS;
  171. }
  172.  
  173. VOID ExtendGfx()
  174. {
  175.     /* Fix which row we're talking about */
  176.     if (my - yt < yb - my) {   /* Find closest row */
  177.         yt = my;               /* change top row */
  178.     } else {
  179.         yb = my;               /* change bottom row */
  180.     }
  181.     if (mx - xl < xr - mx) {
  182.         xl = mx;
  183.     } else {
  184.         xr = mx;
  185.     }
  186. }
  187.  
  188. VOID gfx_frame()
  189. {
  190.     NewFrame[0].x = xl;  NewFrame[0].y = yt;
  191.     NewFrame[1].x = xr;  NewFrame[1].y = yt;
  192.     NewFrame[2].x = xr;  NewFrame[2].y = yb;
  193.     NewFrame[3].x = xl;  NewFrame[3].y = yb;
  194.     NewFrame[4].x = xl;  NewFrame[4].y = yt;
  195.     draw_frame(GfxFrame);
  196. }
  197.  
  198. WORD HandleGfx()
  199. {
  200.     theScreen = WhichScreen();   /* Find out where we are */
  201.     if (!theScreen) {            /* Don't know? Forget it. */
  202.         action = noaction;
  203.         return 0;
  204.     }
  205.       /* Lock everything - find out what happens */
  206.     LockedLayerInfo = &theScreen->LayerInfo;
  207.     LockLayers(LockedLayerInfo);
  208.  
  209.       /* Get a copy. Don't mess with somebody else's RP. */
  210.     CopyMem((char *)&theScreen->RastPort, (char *)&rp, (long)sizeof(struct RastPort));
  211.     SetDrMd(&rp, COMPLEMENT);
  212.  
  213.     xl = theScreen->MouseX + theScreen->ViewPort.RasInfo->RxOffset;
  214.     if (xl < 0) {
  215.         xl = 0;
  216.     }
  217.     if (xl >= theScreen->Width) {  /* Check those corners. Check those corners. */
  218.         xl = theScreen->Width - 1;
  219.     }
  220.     yt = theScreen->MouseY + theScreen->ViewPort.RasInfo->RyOffset;
  221.     if (yt < 0) {
  222.         yt = 0;
  223.     }
  224.     if (yt >= theScreen->Height) {
  225.         yt = theScreen->Height - 1;
  226.     }
  227.     xr = xl;
  228.     yb = yt;
  229.     Ptrn = (SnapRsrc->CrawlPtrn ? SnapRsrc->CrawlPtrn : Pattern[UNIT_FRAME]);
  230.     OFType = 0L;
  231.     gfx_frame();
  232.  
  233.     FOREVER {
  234.         REGISTER LONGBITS sig;
  235.  
  236.         MyTR.tr_time.tv_secs = 0;
  237.         MyTR.tr_time.tv_micro = 500000;
  238.         MyTR.tr_node.io_Command = TR_ADDREQUEST;
  239.         SendIO((struct IORequest *)&MyTR);
  240.  
  241.         sig = Wait(movesignal | clicksignal | cancelsignal |
  242.           donesignal | ticksignal | timersignal);
  243.  
  244.         if (CheckIO((struct IORequest *)&MyTR)) {
  245.             WaitIO((struct IORequest *)&MyTR);
  246.             erase_frame();
  247.             UnlockLayers(LockedLayerInfo);  /* Unlock things */
  248.             sig = Wait(ticksignal);         /* Wait for input handler to become avtive */
  249.             LockLayers(LockedLayerInfo);    /* Re-lock */
  250.               /* I guess I should check to see that the window is still
  251.                  there. Aw, what the heck. Apologies to anyone who gets
  252.                  bitten by this. */
  253.             DisplayBeep(NULL);
  254.             gfx_frame();
  255.         } else {
  256.             AbortIO((struct IORequest *)&MyTR);
  257.             WaitIO((struct IORequest *)&MyTR);
  258.             SetSignal(0, timersignal);
  259.         }
  260.  
  261.         if ((sig & ticksignal) && (SnapRsrc->CrawlPtrn != 0xffff)) {
  262.             crawl_frame(1L);
  263.         }
  264.  
  265.         if (sig & movesignal || sig & clicksignal) {
  266.             mx = theScreen->MouseX + theScreen->ViewPort.RasInfo->RxOffset;
  267.             if (mx < 0) {
  268.                 mx = 0;
  269.             }
  270.             if (mx>=theScreen->Width) {
  271.                 mx = theScreen->Width - 1;
  272.             }
  273.             my = theScreen->MouseY + theScreen->ViewPort.RasInfo->RyOffset;
  274.             if (my < 0) {
  275.                 my = 0;
  276.             }
  277.             if (my>=theScreen->Height) {
  278.                 my = theScreen->Height - 1;
  279.             }
  280.             ExtendGfx();
  281.             gfx_frame();
  282.         }
  283.         if (sig & cancelsignal) {          /* Cancelled? */
  284.             erase_frame();
  285.             UnlockLayers(LockedLayerInfo);
  286.             return 0;
  287.         }
  288.         if (sig & donesignal) {            /* Finished. Copy gfx. */
  289.             struct GfxSnap *GS;
  290.  
  291.             erase_frame();
  292.             if (xl == xr || yt == yb) {
  293.                 action = noaction;
  294.                 UnlockLayers(LockedLayerInfo);
  295.                 return 0;
  296.             }
  297.             if (xr >= theScreen->Width) {
  298.                 xl -= xr - theScreen->Width - 1;
  299.                 xr = theScreen->Width - 1;
  300.             }
  301.             if (yb >= theScreen->Height) {
  302.                 yt -= yb - theScreen->Height - 1;
  303.                 yb = theScreen->Height - 1;
  304.             }
  305.             FixHeights();
  306.             GS = SnapGfx(&rp); /* Snap! */
  307.             UnlockLayers(LockedLayerInfo);
  308.             if (GS) {
  309.                 if (GS->window = opensharedwindow(&Nw)) {
  310.                     if (SnapRsrc->flags & SIMPLEREFRESH) {
  311.                         ModifyIDCMP(GS->window,
  312.                           GS->window->IDCMPFlags | REFRESHWINDOW);
  313.                     }
  314.                     if (Kick36) {
  315.                         GS->topbar = GS->window->BorderTop;
  316.                         GS->leftbar = GS->window->BorderLeft;
  317.                         GS->rightbar = GS->window->BorderRight;
  318.                         GS->bottombar = 10;/*GS->window->BorderBottom;*/
  319.  
  320.                         GS->HProp.TopEdge = -7;
  321.                         GS->HProp.Height = 6;
  322.                     }
  323.  
  324.                     GS->DiskGad.TopEdge    = GS->topbar;
  325.                     GS->DiskGad.LeftEdge   = (Kick36 ? -17 : -14);
  326.                     GS->DiskGad.Width      = (Kick36 ? 18 : 14);
  327.                     GS->ClipGad.TopEdge    = GS->DiskGad.TopEdge + 12;
  328.                     GS->ClipGad.LeftEdge   = (Kick36 ? -17 : -14);
  329.                     GS->ClipGad.Width      = (Kick36 ? 18 : 14);
  330.                     GS->HProp.GadgetRender = (APTR)&GS->HImage;
  331.                     GS->HProp.SpecialInfo  = (APTR)&GS->HInfo;
  332.                     GS->VProp.TopEdge      = 
  333.                       GS->ClipGad.TopEdge + (Kick36 ? 14 : 15);
  334.                     GS->VProp.LeftEdge     = (Kick36 ? 5 : 7) - GS->rightbar;
  335.                     GS->VProp.Width        = GS->rightbar - (Kick36 ? 8 : 10);
  336.                     GS->VProp.Height       = 
  337.                       (Kick36 ? -28 : -27) - GS->bottombar - GS->topbar;
  338.                     GS->VProp.GadgetRender = (APTR)&GS->VImage;
  339.                     GS->VProp.SpecialInfo  = (APTR)&GS->VInfo;
  340.  
  341.                     GS->DiskGad.NextGadget = &GS->ClipGad;
  342.                     GS->ClipGad.NextGadget = &GS->VProp;
  343.                     GS->VProp.NextGadget   = &GS->HProp;
  344.                     GS->HProp.NextGadget   = NULL;
  345.  
  346.                     AddGList(GS->window, &GS->DiskGad, -1, -1, NULL);
  347.                     GS->window->UserData = (BYTE *)GS;
  348.                       /* Put gfx in our new window */
  349.                     AdjustSize(GS);
  350.                 } else {
  351.                     FreePlanes(&GS->BM, GS->width, GS->height);
  352.                     Kill(GS);
  353.                 }
  354.             } else { /* Good question */
  355.             }
  356.             action = noaction;
  357.             return 0;
  358.         }
  359.     }
  360. }
  361.